﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Transactions;
using Deeper.Common;
using System.Data;
using System.Xml;
using System.Linq.Expressions;

namespace Deeper.DataAccess
{
	public static class HDbHelper
	{
		public static DataContext CreateDatabase(this DataContext db)
		{
			return db ?? new DataContext();
		}

		/// <summary>
		/// 执行带Scope事务的方法（仅支持sql，而且要数据库与应用在同一台服务器）
		/// </summary>
		/// <param name="func"></param>
		/// <param name="Level"></param>
		public static void Transaction(Action func, TransactionScopeOption Level = TransactionScopeOption.Required)
		{
			using (TransactionScope sc = new TransactionScope(Level))
			{
				func();
				sc.Complete();
			}
		}


		/// <summary>
		/// 将datatale转换成泛型对象
		/// </summary>
		/// 
		/// <param name="dt"></param>
		public static IList<T> AsList<T>(this DataTable dt) where T : class,IModel, new()
		{
			HTableAttribute currentTableInfo = DatabaseScheme.GetTableInfo(typeof(T));
			IList<T> list = new List<T>();
			if (dt.IsNull()) throw new ArgumentNullException("Datatable不能为空");
			if (dt.Rows.Count > 0)
			{
				dt.Rows.Cast<DataRow>().ToList().ForEach(dr =>
				{
					T tmp = currentTableInfo.GetModel<T>(dr);
					list.Add(tmp);
				});
			}
			return list;
		}

		/// <summary>
		/// 把datarow转换为实体对象
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="dr"></param>
		/// <returns></returns>
		public static T AsEntity<T>(this DataRow dr) where T : class,IModel, new()
		{
			HTableAttribute currentTableInfo = DatabaseScheme.GetTableInfo(typeof(T));
			T tmp = currentTableInfo.GetModel<T>(dr);
			return tmp;
		}


		/// <summary>
		/// 保存实体方法，id＝0时插入，非0时更新
		/// </summary>
		/// <param name="db"></param>
		/// <param name="t"></param>
		/// <returns></returns>
		public static IModel Save(this IModel model, DataContext db = null)
		{
			db = HDbHelper.CreateDatabase(db);
			return db.Save(model);
		}

		///// <summary>
		///// 校验唯一字段
		///// </summary>
		///// <param name="t"></param>
		///// <param name="db"></param>
		///// <returns></returns>
		public static Validator<dynamic> CheckUniquenese(this IModel model, DataContext db = null)
		{
			db = HDbHelper.CreateDatabase(db);
			HTableAttribute currentTableInfo = DatabaseScheme.GetTableInfo(model.GetType());
			Validator<dynamic> valid = new Validator<dynamic>(model);
			HColumnAttribute pk = currentTableInfo.PrimaryKey[0];

			object pkValue = pk.Field.GetValue(model, null);
			currentTableInfo.Columns.Cast<HColumnAttribute>()
			.Where(s => !s.IsPrimary && !s.IsIdentity && s.IsUniqueness)
			.ToList().ForEach(s =>
			{
				object value = s.Field.GetValue(model, null);

				if (!value.IsNull())
				{
					int iCount = 0;
					if (!pkValue.IsNull())
						iCount = db.GetCount(currentTableInfo.sqlCount, string.Format("{0} = {{0}} and {1} != {{1}}", s.ColumnName, pk.ColumnName), value, pkValue);
					else
						iCount = db.GetCount(currentTableInfo.sqlCount, string.Format("{0} = {{0}}  ", s.ColumnName), value);
					if (iCount > 0) valid.ErrorMessage.Add(string.Format("{0}不可重复", s.Remake));
				}
			});
			return valid;
		}

		///// <summary>
		///// 校验不可为空字段
		///// </summary>
		///// <param name="t"></param>
		///// <param name="db"></param>
		///// <returns></returns>
		public static Validator<dynamic> CheckNullable(this IModel model)
		{
			Validator<dynamic> valid = new Validator<dynamic>(model);
			HTableAttribute currentTableInfo = DatabaseScheme.GetTableInfo(model.GetType());
			currentTableInfo.Columns.Cast<HColumnAttribute>()
			.Where(s => !s.IsPrimary && !s.IsIdentity && !s.IsNullable)
			.ToList().ForEach(s =>
			{
				object value = s.Field.GetValue(model, null);
				if (value.IsNull())
					valid.ErrorMessage.Add(string.Format("[{0}]不可为空", s.Remake));
			});
			return valid;
		}

	}
}
